package top.mccat.filesystem.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import top.mccat.filesystem.bean.MyFile;
import top.mccat.filesystem.mapper.FileMapper;
import top.mccat.filesystem.service.FileService;
import top.mccat.filesystem.utils.EssentialsConstant;
import top.mccat.filesystem.utils.checker.StringUtils;
import top.mccat.filesystem.utils.io.FileUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.FileAlreadyExistsException;
import java.sql.Date;
import java.sql.Timestamp;
import java.util.List;

/**
 * @author JMY
 * @Description TODO
 * @Version 1.0.0
 * @Date 2023/2/22 10:16
 * @Created by JMY
 */
@Service
@Slf4j
public class FileServiceImpl implements FileService {
    @Autowired
    private FileUtils fileUtils;

    @Autowired
    private FileMapper fileMapper;

    @Override
    @Transactional(rollbackFor = IOException.class)
    public MyFile uploadFile(MultipartFile[] files, String fileRemark, Integer fileParent, Long author, boolean isCover) throws IOException {
        for(MultipartFile file : files){
            //获取文件名
            String fileName = file.getOriginalFilename();
            if(StringUtils.isBlank(fileName)){
                throw new IOException("文件名为空，请确定上传文件正确！");
            }
            long size = file.getSize();
            String fileSuffix = fileName.substring(fileName.lastIndexOf("."));
            MyFile myFile = new MyFile();
            myFile.setFileName(fileName);
            myFile.setFileSuffix(fileSuffix);
            myFile.setFileSize(size);
            myFile.setFileRemark(fileRemark);
            myFile.setFileParent(fileParent);
            List<MyFile> myFiles = fileMapper.selectFile(myFile);
            if(myFiles != null && myFiles.size() > 0){
                //如果用户不相同则让其也拥有该文件
                if(!author.equals(myFiles.get(0).getFileAuthor())){
                    //进行日期转换
                    myFile.setFileDate(new Date(System.currentTimeMillis()));
                    myFile.setFileAuthor(author);
                    fileMapper.insertFile(myFile);
                    log.debug("文件上传到数据库成功，由于文件相同故不写入！");
                    return myFile;
                }
                throw new FileAlreadyExistsException("已存在相同文件！");
            }
            //进行日期转换
            myFile.setFileDate(new Date(System.currentTimeMillis()));
            myFile.setFileAuthor(author);
            fileMapper.insertFile(myFile);
            log.debug("文件上传到数据库成功，开始写入！");
            //上传文件
            fileUtils.uploadFile(file);
        }
        return null;
    }

    @Override
    public List<MyFile> listFiles(MyFile file, boolean isAdmin) {
        return fileMapper.selectFile(file);
    }

    @Override
    public void downloadFile(MyFile file, HttpServletResponse httpServletResponse) throws IOException{
        List<MyFile> myFiles = fileMapper.selectFile(file);
        if(myFiles == null || myFiles.size() == 0){
            throw new FileNotFoundException("文件不存在！请确认下载文件是否正确！");
        }
        fileUtils.downloadFile(myFiles.get(0), httpServletResponse);
    }

    @Override
    public void deleteFile(MyFile file) throws IOException {
        Long author = file.getFileAuthor();
        file.setFileAuthor(null);
        file.setFileId(0);
        List<MyFile> myFiles = fileMapper.selectSameFile(file);
        if(myFiles == null || myFiles.size() == 0){
            throw new FileNotFoundException("文件不存在！该文件已被删除！");
        }
        //证明不止一个人拥有该文件
        if(myFiles.size() > 1){
            //获取该条进行删除
            for(MyFile f : myFiles){
                if(author.equals(f.getFileAuthor())){
                    fileMapper.deleteFile(f);
                    return;
                }
            }
        }
        //反之删除该文件
        fileMapper.deleteFile(myFiles.get(0));
        fileUtils.deleteFile(myFiles.get(0));
    }

}
